'use strict'
const BaseService = require('./base');
const rp = require('request-promise');
const StringUtil = require('../utils/StringUtil');
const ResponseUtil = require('../utils/ResponseUtil');


class NotifyService extends BaseService {

    async existNotify(goodsId) {
        let sql = 'select id from t_notify where obj_type=? and obj_id=? and category=? ';
        let result = await this.executeSqlFirst(sql, [NotifyConstant.OBJ_TYPE.GOODS, goodsId, NotifyConstant.CATEGORY.FOLLOW_NEW]);
        return result ? true : false;
    }


    //新增关注上新通知
    async addFollowNewNotify({goodsId, fromUserId}) {
        let exist = await this.existNotify(goodsId);
        if (!exist) {
            let sql = 'select user_id from t_user_follow where shop_user_id=? ';
            let list = await this.executeSql(sql, [fromUserId]);

            for (let i = 0; i < list.length; i++) {
                let params = {
                    category: NotifyConstant.CATEGORY.FOLLOW_NEW,
                    title: '发布了新的宠物',
                    content: '发布了新的宠物',
                    fromUserId: fromUserId,
                    toUserId: list[i].userId,
                    objType: NotifyConstant.OBJ_TYPE.GOODS,
                    objId: goodsId
                };
                await this.insertNotify(params);
            }
        }
        return 1;
    }


    async insertNotify({category, title, content, fromUserId, toUserId, objType, objId,}) {
        let params = {
            category: category,
            title: title,
            content: content,
            from_user_id: fromUserId,
            to_user_id: toUserId,
            obj_type: objType,
            obj_id: objId,
            group_type: 'single'
        };

        await this.executeInsert('t_notify', params);

        return 1;
    }


    async getNotifyToUserNos(notifyId) {
        let sql = 'select * from t_notify_touserid where notify_id=? order by id asc ';
        let result = await this.executeSql(sql, [notifyId]);
        let list = [];
        result.map(function (item) {
            list.push(item.toUserId);
        });
        return list;
    }

    async getSystemMessageList({keyword, groupType, pageNum, pageSize}) {
        let sql = `select * from t_notify a where a.category=? and a.valid=1`;
        let options = [NotifyConstant.CATEGORY.SYSTEM];
        if (groupType) {
            sql += ` and a.group_type=? `;
            options.push(groupType);
        }
        if (keyword) {
            sql += ` and (a.title like "%"?"%" or a.content like "%"?"%" )`;
            options.push(keyword);
            options.push(keyword);
        }
        sql += " order by create_time desc ";
        sql = this.addMysqlPageSize(sql, pageNum, pageSize);
        let result = await this.queryPageData(sql, options);
        let list = result.list;
        await Promise.all(list.map(async (item) => {
            if (item.groupType === 'single') {
                item.toUserNos = await this.getNotifyToUserNos(item.id);
            } else {
                item.toUserNos = [];
            }

            let sql = 'select * from t_notify_read b where b.notify_id=?';
            const readObj = await this.executeSqlFirst(sql,[item.id]);
            item.isRead = readObj?1:0;
        }));
        return result;
    }

    async getSystemMessageDetail({id}) {
        if (!id) {
            return ResponseUtil.retArgErr();
        }
        let sql = `select * from t_notify a where a.category=? and a.valid=1 and a.id=?`;
        let result = await this.executeSqlFirst(sql, ['system', id]);
        if (result) {
            if (result.groupType === 'single') {
                result.toUserNos = await this.getNotifyToUserNos(result.id);
            } else {
                result.toUserNos = [];
            }
        }
        return result;
    }

    async deleteSystemMessage() {
        let id = this.ctx.params.id;
        if (!id) {
            return ResponseUtil.retArgErr();
        }
        let sql = 'update t_notify set valid=0 where id=?';
        return await this.executeSqlSucc(sql, [id]);
    }

    async addSystemMessage({title, content, toUserNos = [], groupType}) {
        if (!title || !content || !['all', 'single'].includes(groupType)) {
            return ResponseUtil.retArgErr();
        }
        if ('single' === groupType && (!toUserNos || toUserNos.length === 0)) {
            return ResponseUtil.retArgErr();
        }

        if (groupType === 'all') {
            let params = {
                category: NotifyConstant.CATEGORY.SYSTEM,
                title: title,
                content: content,
                from_user_id: DefaultUser.USER_ID,
                to_user_id: null,
                group_type: groupType
            };
            await this.executeInsert('t_notify', params);
        } else {
            toUserNos = toUserNos.map(item => item.replace(/\s+/g, ''));
            let sql = 'select id from t_user where user_no in (?)';
            let userList = await this.executeSql(sql, [toUserNos]);
            if (userList.length != toUserNos.length) {
                return ResponseUtil.retErr('存在无效用户');
            }

            let params = {
                category: NotifyConstant.CATEGORY.SYSTEM,
                title: title,
                content: content,
                from_user_id: DefaultUser.USER_ID,
                to_user_id: null,
                group_type: groupType
            };
            let insertResult = await this.executeInsert('t_notify', params);
            let notifyId = insertResult.insertId;

            await Promise.all(userList.map(async (item) => {
                let params = {
                    notify_id: notifyId,
                    to_user_id: item.id
                };
                await this.executeInsert('t_notify_touserid', params);
            }));

        }
        return 1;
    }


    async updateSystemMessage({title, content, toUserNos = [], id}) {
        if (!title || !content || !id) {
            return ResponseUtil.retArgErr();
        }
        let sql = 'select * from t_notify where id = ? and category=?';
        let object = await this.executeSqlFirst(sql, [id, NotifyConstant.CATEGORY.SYSTEM]);
        if (!object) {
            return ResponseUtil.retErr('no such notify')
        }
        if (object.groupType === 'single' && toUserNos.length === 0) {
            return ResponseUtil.retErr('请至少给一个用户发送消息');
        }

        if (object.groupType === 'single' && toUserNos.length > 0) {
            toUserNos = toUserNos.map(item => item.replace(/\s+/g, ''));
            sql = 'select id from t_user where user_no in (?)';
            let userList = await this.executeSql(sql, [toUserNos]);
            if (userList.length != toUserNos.length) {
                return ResponseUtil.retErr('存在无效用户');
            }

            sql = 'delete from t_notify_touserid where notify_id=? ';
            await this.executeSqlSucc(sql, [id]);

            await Promise.all(userList.map(async (item) => {
                let params = {
                    notify_id: id,
                    to_user_id: item.id
                };
                await this.executeInsert('t_notify_touserid', params);
            }));
        }

        sql = 'update t_notify set title=?,content=? where id=?';
        await this.executeSqlSucc(sql, [title, content, id]);

        return 1;
    }

}

module.exports = NotifyService;
